package com.vanysoft.business.system.operateLogs.aop;

import com.vanysoft.business.sys.entity.Api;
import com.vanysoft.business.sys.entity.UserInfo;
import com.vanysoft.business.system.operateLogs.entity.TSystemApiAccessLogs;
import com.vanysoft.business.system.operateLogs.service.SystemApiAccessLogsService;
import com.vanysoft.framework.exception.VanySoftBaseException;
import com.vanysoft.framework.messagesource.MessageCodeConstant;
import com.vanysoft.framework.redis.RedisConstants;
import com.vanysoft.framework.redis.RedisService;
import com.vanysoft.framework.utils.JSONResponse;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 类名称：ApiLogInterceptor
 * 类描述：记录接口日志入口类
 * 创建人：X
 * 创建时间：2017年9月19日下午6:06:40
 * 修改人：X
 * 修改时间：2017年9月19日
 * 版本信息：@version 1.0
 * Copyright (c) 2017SharpClaw-版权所有
 * 修改备注：
 */
@Aspect
@Component
public class ApiLogInterceptor {


    @Autowired
    private RedisService redisService;
    @Autowired
    private SystemApiAccessLogsService systemApiAccessLogsService;

    /**
     * Function Name               controllerMethodPointcut
     *
     * @return
     * @throws VanySoftBaseException
     * @description 定义切面入口
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年9月19日下午6:10:52          KING          Initial
     * *********************************************************************
     */
    @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
    public void controllerMethodPointcut() {
    }

    /**
     * Function Name               interceptor
     *
     * @param
     * @return
     * @throws Throwable
     * @description 指定拦截器规则
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年9月19日下午6:12:59          x          Initial
     * *********************************************************************
     */
    @Around("controllerMethodPointcut()")
    public Object interceptor(ProceedingJoinPoint pjp) throws Throwable {
        String oprLogMark = "_oprLog";
        // 获取当前url的值
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();
        String url = request.getServletPath();

        boolean isLog;
        TSystemApiAccessLogs accessLog = new TSystemApiAccessLogs();
        List<Api> apis = (List<Api>) redisService.get(RedisConstants.API_LIST);
        if (apis == null || apis.size() == 0) {
            isLog = false;
        } else {
            List<Api> currentApis = apis.stream().filter(r -> Objects.equals(r.getUri(), url)).collect(Collectors.toList());
            if (currentApis == null || currentApis.size() == 0) {
                isLog = false;
            } else {
                Api api = currentApis.get(0);
                isLog = api.getLog();
                if (isLog) {
                    accessLog.setApiId(api.getId());
                }
            }
        }

        String token = request.getParameter("token");
        if (token == null || "".equalsIgnoreCase(token)) {
            isLog = false;
        }
        if (isLog) {
            String accessid = UUID.randomUUID().toString().replaceAll("-", "");
            UserInfo userInfo = redisService.getUserInfo(token);
            if (userInfo == null) {
                throw new VanySoftBaseException(MessageCodeConstant.LoginConstant.LOGIN_TIME_OUT);
            }
            String ip = request.getRemoteAddr();
            accessLog.setAccessid(accessid);
            accessLog.setUserId(userInfo.getId());
            accessLog.setUserName(userInfo.getChineseName());
            accessLog.setAccessTime(new Date());
            accessLog.setLoginIp(ip);
            Enumeration<String> enu = request.getParameterNames();
            StringBuffer buf = new StringBuffer("");
            while (enu.hasMoreElements()) {
                String paraName = enu.nextElement();
                buf.append(paraName).append(":").append(request.getParameter(paraName)).append(";");
            }
            if (buf.length() >= 2000) {
                buf = new StringBuffer(buf.substring(0, 2000));
            }
            accessLog.setOperationContent(buf.toString());
            //systemApiAccessLogsService.insertSystemApiAccessLogs(obj);
            redisService.set(token + oprLogMark, accessLog);
        }
        // 一切正常的情况下，继续执行被拦截的方法
        Object result = pjp.proceed();

        accessLog = (TSystemApiAccessLogs) redisService.get(token + oprLogMark);
        if (null != accessLog) {
            //String keyStr = key.toString();
            //obj1.setAccessid(keyStr);
            if (isLog) {
                JSONResponse r = (JSONResponse) result;
                accessLog.setRspCode(r.getRspCode());
                accessLog.setRspMsg(r.getRspMsg());
                accessLog.setErrMsg(r.getDebuggerErrorMsg());
            } else {
                accessLog.setRspCode("1111");
                accessLog.setRspMsg("操作失败");
                accessLog.setErrMsg(String.valueOf(result));
            }
            //用来替代REPLACE INTO
            try {
                systemApiAccessLogsService.insertSystemApiAccessLogs(accessLog);
            } catch (Exception e) {
                systemApiAccessLogsService.updateSystemApiAccessLogs(accessLog);
            }
            redisService.delete(token + oprLogMark);
        }
        return result;
    }

}
